home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1999 November / Macworld (1999-11).dmg / Shareware World / Comms & Internet / DXF to VRML97 1.0.1 / src / dxf2vrml97.cpp < prev    next >
C/C++ Source or Header  |  1999-08-24  |  7KB  |  346 lines

  1. // Original code from DIME distribtion, available from http://www.sim.no/
  2. // Released under GPL v2 (see the DIME distribution)
  3.  
  4. // Converted from VRML 1.0 to ISO VRML 97 and prepared to work
  5. // nicely with DropUnix by Michael.Louka@hrp.no
  6.  
  7.  
  8. #include <dime/entities/Entity.h>
  9. #include <dime/Input.h>
  10. #include <dime/Model.h>
  11. #include <dime/State.h>
  12. #include <dime/util/BSPTree.h>
  13. #include <stdlib.h>
  14.  
  15. #ifdef macintosh
  16. #include "console.h"
  17. #include "unix.h"
  18. #include "SIOUX.h"
  19. #include "Main.h"
  20. #endif
  21.  
  22.  
  23. class faceset_data {
  24. public:
  25.   faceset_data() {
  26.   }
  27.   ~faceset_data() {
  28.   }
  29.   void clean() {
  30.     bspTree.clear();
  31.     indices.makeEmpty();
  32.   }
  33. public:
  34.   dimeArray <int> indices;
  35.   dimeBSPTree bspTree;
  36. }; 
  37.  
  38. // some static arrays 
  39. static dimeArray <int> indexarray;
  40. static dimeArray <dimeVec3f> vertexarray;
  41. static faceset_data *facesets;
  42.  
  43. static bool my_dime_callback(const dimeState * const state, 
  44.                  dimeEntity *entity, void *);
  45. static void convertColor(faceset_data *data, const int colnum, FILE *out);
  46.  
  47.  
  48.  
  49. //
  50. //  Call this to initialize static members.
  51. //
  52. static void
  53. init()
  54. {
  55.   if (facesets) delete [] facesets;
  56.   facesets = new faceset_data[255];
  57. }
  58.  
  59. //
  60. //  Call this to free static data.
  61. //
  62. static void
  63. end()
  64. {
  65.   delete [] facesets;
  66.   facesets = NULL;
  67.   indexarray.makeEmpty();
  68.   vertexarray.makeEmpty();
  69. }
  70.  
  71. static bool
  72. convertDxf2Wrl(const char * const dxffilename,
  73.            const char * const wrlfilename)
  74. {
  75.   dimeInput in;
  76.   if (!in.setFile(dxffilename)) {
  77.     return false;
  78.   }
  79.   
  80.   dimeModel model;
  81.   if (!model.read(&in)) {
  82.     fprintf(stderr,"Read error in line: %d\n", in.getFilePosition());
  83.     return false;
  84.   }
  85.  
  86.   FILE *out = fopen(wrlfilename, "w");
  87.   if (!out) return false;
  88.   
  89.   fprintf(out,
  90.       "#VRML V2.0 utf8\n\n"
  91.       "Group {\n  children [\n");
  92.   
  93.   model.traverseEntities(my_dime_callback, &model, 
  94.              false, true, false);
  95.   
  96.   for (int i = 0; i < 255; i++) {
  97.     convertColor(&facesets[i], i+1, out);
  98.   }
  99.  
  100.   fprintf(out,"  ]\n}\n");
  101.   return true;
  102. }
  103.  
  104. static void
  105. convertColor(faceset_data *data, const int colnum, FILE *out)
  106. {
  107.   int i;
  108.  
  109.   int icnt = data->indices.count();
  110.   int vcnt = data->bspTree.numPoints();
  111.  
  112.   if (vcnt == 0 || icnt == 0) return;
  113.  
  114.   // If not present, append a -1 at the end of the index array
  115.   if (data->indices[icnt-1] >= 0) data->indices.append(-1);
  116.  
  117.  
  118.   dimeBSPTree &bsptree = data->bspTree;
  119.  
  120.   fprintf(out,"    Shape {\n");
  121.  
  122.   float r, g, b;
  123.   dimeLayer::colorToRGB(colnum, r, g, b); 
  124.  
  125.   fprintf(out,"      appearance Appearance {\n"
  126.       "        material Material {\n"
  127.       "          diffuseColor %g %g %g\n"
  128.       "          specularColor 1 1 1\n"
  129.       "        }\n      }\n", r,g,b);
  130.   
  131.   fprintf(out,"      geometry IndexedFaceSet {\n"
  132.       "        solid FALSE\n"
  133.       "        coord Coordinate {\n"
  134.       "          point [\n");
  135.  
  136.   int first = 1;
  137.   for (i = 0; i < vcnt; i++) {
  138.     dimeVec3f tmp;
  139.     bsptree.getPoint(i, tmp);
  140.     if (first) {
  141.       fprintf(out,"            %g %g %g", tmp[0], tmp[1], tmp[2]);
  142.       first = 0;
  143.     }
  144.     else
  145.       fprintf(out,",\n            %g %g %g", tmp[0], tmp[1], tmp[2]);
  146.   }
  147.   
  148.   fprintf(out,"\n          ]\n        }\n");
  149.   
  150.   bsptree.clear();
  151.   
  152.   if (icnt) {
  153.     fprintf(out,"        coordIndex [\n          ");
  154.     int *ptr = data->indices.arrayPointer();
  155.     int facecnt = 1;
  156.     
  157.     for (i = 0; i < icnt-1; i++) {
  158.       int index = *ptr++;
  159.       fprintf(out, "%d,", index);
  160.       if (index < 0) {
  161.     facecnt++;
  162.     if ((facecnt & 3) == 0) fprintf(out,"\n          "); 
  163.       }
  164.     }
  165.     fprintf(out, "-1\n        ]\n      }\n"); 
  166.     data->indices.makeEmpty(); // free memory
  167.   }
  168.   
  169.   fprintf(out,"    }\n");
  170. }
  171.  
  172. static int
  173. get_color_index(dimeEntity *entity)
  174. {
  175.   int colnum = entity->getColorNumber();
  176.   if (colnum == 256) {
  177.     const dimeLayer *layer = entity->getLayer();
  178.     colnum = layer->getColorNumber();
  179.   }
  180.   return colnum;
  181. }
  182.  
  183. bool 
  184. my_dime_callback(const dimeState * const state, 
  185.          dimeEntity *entity, void *)
  186. {
  187.   static int blockcolidx = 7; // to support BYBLOCK color
  188.  
  189.   dimeMatrix matrix = state->getMatrix();
  190.   
  191.   indexarray.setCount(0);
  192.   vertexarray.setCount(0);
  193.  
  194.   float thickness;
  195.   dimeVec3f extrusionDir;
  196.  
  197.   dimeEntity::GeometryType type = 
  198.     entity->extractGeometry(vertexarray, 
  199.                 indexarray,
  200.                 extrusionDir,
  201.                 thickness);
  202.   
  203.   if (type == dimeEntity::NONE) return true;
  204.  
  205.   int id = entity->typeId();
  206.   
  207.   if (extrusionDir != dimeVec3f(0,0,1)) {
  208.     if (id == dimeBase::dimeTraceType || 
  209.     id == dimeBase::dimeSolidType ||
  210.     id == dimeBase::dimeCircleType ||
  211.     thickness == 0.0) {
  212.       dimeMatrix m;
  213.       dimeEntity::generateUCS(extrusionDir, m);
  214.       matrix.multRight(m);
  215.     }
  216.   }
  217.   int colidx = get_color_index(entity);
  218.  
  219.   if (colidx == 0) { // BYBLOCK
  220.     colidx = blockcolidx;
  221.   }
  222.   // negative color means layer turned off, but who cares
  223.   if (colidx < 0) colidx = -colidx; 
  224.   colidx--; // to use lookup table 
  225.  
  226.   if (colidx < 0 || colidx > 255) { // safety check
  227.     colidx = 6; // should never happen
  228.   }
  229.  
  230.   dimeBSPTree &bsp = facesets[colidx].bspTree;
  231.   dimeArray <int> &idx = facesets[colidx].indices;
  232.  
  233.   int i,n,numidx;
  234.   n = vertexarray.count();
  235.   numidx = indexarray.count();
  236.  
  237.   if (n == 0) return true;
  238.  
  239.   switch(type) {
  240.   case dimeEntity::POLYGONS:
  241.     //
  242.     // Extruded polygons not supported
  243.     //
  244.     if (numidx == 0) {
  245.       for (i = 0; i < n; i++) {
  246.     dimeVec3f tmp = vertexarray[i];
  247.     matrix.multMatrixVec(tmp);
  248.     idx.append(bsp.addPoint(tmp));
  249.       }
  250.       idx.append(-1);
  251.     }
  252.     else {
  253.       for (i = 0; i < numidx; i++) {
  254.     int index = indexarray[i];
  255.     if (index >= 0) {
  256.       dimeVec3f tmp = vertexarray[index];
  257.       matrix.multMatrixVec(tmp);
  258.       idx.append(bsp.addPoint(tmp));
  259.     }
  260.     else idx.append(-1);
  261.       }
  262.       if (idx.count() && idx[idx.count()-1] >= 0)
  263.     idx.append(-1);
  264.     }
  265.     break;
  266.   case dimeEntity::LINES:
  267.   case dimeEntity::POINTS:
  268.     // just insert code here :-)
  269.     break;
  270.   default:
  271.     break;
  272.   }
  273.   return true;
  274. }
  275.  
  276.  
  277. int main(int argc, char **argv)
  278. {
  279.  
  280. #ifdef macintosh
  281.   SIOUXSettings.asktosaveonclose = 0;
  282.   _fcreator = 'CMPL';
  283.   _ftype = 'TEXT';
  284. #endif
  285.  
  286.     for (int i = 1; i <= (argc - 1); i++) {
  287.  
  288.       init();
  289.       
  290.       // Construct the full filepath for the VRML file:
  291.       char* dxfFullPath = argv[i];
  292.       char* wrlFileName = new char[32];
  293.       char* wrlFullPath = new char[strlen(dxfFullPath)+4];
  294.       strcpy (wrlFullPath, dxfFullPath);
  295.  
  296.       if (wrlFileName != NULL ) {
  297.          
  298.        char* sPos;
  299.        char* ePos;
  300.  
  301.        sPos = strrchr( dxfFullPath, ':' );
  302.  
  303.        if ( sPos != NULL )
  304.           sPos++;
  305.        else
  306.           sPos = (char*)dxfFullPath;
  307.    
  308.        strncpy( wrlFileName, sPos, 26 );
  309.      
  310.        ePos = strstr( wrlFileName+1, ".dxf" );
  311.      
  312.        if ( ePos == NULL )
  313.          ePos = strstr( wrlFileName+1, ".DXF" );
  314.  
  315.        if ( ePos != NULL )
  316.          *ePos = '\0';
  317.          
  318.        strcat(wrlFileName,".wrl");
  319.  
  320.        sPos = strrchr( wrlFullPath, ':' );
  321.  
  322.        if ( sPos != NULL ) {
  323.           sPos++;
  324.           strcpy (sPos, wrlFileName);
  325.        }
  326.        else {
  327.            free (wrlFullPath);
  328.            wrlFullPath = wrlFileName;
  329.        }
  330.  
  331.       // Do the conversion
  332.           if (!convertDxf2Wrl(dxfFullPath, wrlFullPath)) {
  333.             fprintf(stderr,"Error while converting.\n");
  334.           }
  335.           if (wrlFileName)
  336.             free (wrlFileName);
  337.           if (wrlFullPath)
  338.             free (wrlFullPath);
  339.       }
  340.       end();
  341.     }
  342. exit(1);
  343. }
  344.  
  345.  
  346.